#ifndef _EDITOR_HPP_
#define _EDITOR_HPP_

#include <stdexcept>
#include <vector>
#include "../ged/typedefs.hpp"

namespace ged {

//! Klasa reprezentująca edytor graficzny
/*!
 * Główna klasa biblioteki ged, za pomocą której wykonujemy komendy
 * operujące na obrazkach. Klasa Implementuje wzorzec Singleton, oraz
 * może być przedmiotem obserwacji przez klasę dziedziczącą po
 * ged::Observer.
 *
 * \sa ged::Image
 * \sa ged::ImageLayer
 */
class Editor {
public:

	//! Klasa wyjątku braku obrazka
	/*!
	 * Wyjątek rzucany w sytuacjach gdy następuje próba wykonania
	 * operacji na obrazku, który jeszcze nie został utworzony.
	 */
	class NoImageException : public std::exception {};

	//! Zwraca instację edytora
	/*!
	 * \return wskaźnik na instancję edytora
	 */
	static Editor* getInstance();

	//! Wykonuje komendę
	/*!
	 * \param com sprytny wskżnik na obiekt komendy
	 * \sa ged::Command
	 */
	void execute(PCommand com);

	//! Cofa ostatnią komendę
	void unExecute();

	//! Wykonuje ponownie ostatnią komendę
	void redo();

	//! Ustawia obserwartora, który będzie powiadamiany o zmianach
	//! dokonywanych na obrazku
	void setObserver(const PObserver&);

	//! Powiadamia obserwtora o zmianach dokonanych na obrazku
	void notify() const;

	//! Dodaje do obrazka nową warstwę skojarzoną z obrazem GIL
	/*!
	 * Pierwsza dodana warstwa jest traktowana jako tło obrazka i
	 * do niej będzie dopasowany rozmiar oraz początek
	 * ukłądu współrzędnych obrazka.
	 *
	 * \param image obraz GIL skojarzony z nową warstwą
	 */
	void addImageLayer(const PGILImage& image);

	//! Zwraca obrazek składający się z wielu warstw
	/*
	 * \return sprytny wskaźnik na obrazek
	 * \sa ged::Image
	 */
	const PImage getImage() const;

private:
	//! Prywatny konstruktor
	Editor();
	//! Prywatny konstruktor kopiujący
	Editor(const Editor&);
	//! Prywatny destruktor
	~Editor();

	//! Wskaźnik na instancję edytora
	static Editor *instance;
	//! Wektor komend
	std::vector<PCommand> com_;
	//! Licznik komend
	std::size_t command_count_;
	//! Obrazek przechowujący wiele warstw
	PImage image_;
	//! Obserwator
	PObserver observer_;
};

} //namespace ged

#endif // _EDITOR_HPP_
